# -*- coding:utf-8 -*-

import warnings
warnings.filterwarnings("ignore")

from xgboost import XGBRegressor
import lightgbm as lgb
from sklearn.model_selection import TimeSeriesSplit, GridSearchCV, RandomizedSearchCV

import numpy as np
from django.shortcuts import render
from django.contrib import auth
from django.http import HttpResponse
from hxwkpi.settings import BASE_DIR,STATIC_URL

import requests,json
import pandas as pd
from chinese_calendar import is_workday, is_holiday,get_holiday_detail,is_in_lieu
import xgboost as xgb
from sklearn.ensemble import RandomForestRegressor

import datetime as dt
from sklearn.preprocessing import MinMaxScaler
from sklearn import metrics
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras import backend as K #转换为张量

# from report.collector import ReportCollector
# from report import report_service
from copy import deepcopy

xgb.set_config(verbosity=0)


def index(request):
    if request.method == 'GET':
       return render(request, "apitest.html")




#######################################################################################

#######################################################################################

#增加时间特征值
def add_time_features(ne_datetime):
    ne_date=pd.DataFrame()
    #print('zheli----kaishi',ne_datetime)
    ne_date['date_range']=ne_datetime
    ne_date['hour'] = ne_datetime.dt.hour  # 小时  21
    ne_date['minute'] = ne_datetime.dt.minute  # 分钟 01
    # 日期特征
    ne_date['date'] = ne_datetime.dt.date # 日期  20220522
    ne_date['year'] = ne_datetime.dt.year  # 年  2022
    ne_date['month'] = ne_datetime.dt.month  # 月  5
    ne_date['day'] = ne_datetime.dt.day  # 日 22

    ne_date['dayofweek'] = ne_datetime.dt.dayofweek  # 一周中的第几天，0-6表示周一到周日，
    ne_date['dayofyear'] = ne_datetime.dt.dayofyear  # 一年中的第几天
    ne_date['quarter'] = ne_datetime.dt.quarter  # 季度

####由于chinese_canlender只能处理2024年之前的日期，所以分批处理。
    this_year=2024
    if not ne_date[ne_date['year']>this_year].empty:
        ne_date_2022_after=ne_date[ne_date['year']>this_year]
        #print(ne_date_2022_after.loc[(ne_date_2022_after['dayofweek']!=5)& (ne_date_2022_after['dayofweek']!=6)])
        ne_date_2022_after['is_workday']=0
        ne_date_2022_after['is_holiday']=0

        ne_date_2022_after.loc[(ne_date_2022_after['dayofweek']!=5)& (ne_date_2022_after['dayofweek']!=6),'is_workday']=1
        ne_date_2022_after.loc[(ne_date_2022_after['dayofweek']==5)|(ne_date_2022_after['dayofweek']==6),'is_holiday']=1

        ne_date_2022_after['holiday_code']=None

        ne_date_2022=ne_date[ne_date['year']<=this_year]

        # 节假日特征
        ne_date_2022['is_workday'] = pd.DataFrame([is_workday(x) for x in ne_date_2022['date']]).astype('int')  # 是否工作日
        ne_date_2022['is_holiday'] = pd.DataFrame([is_holiday(x) for x in ne_date_2022['date']]).astype('int')  # 是否节假日
        ne_date_2022_holiday=[]
        for x in ne_date_2022['date']:
            holiday_code = get_holiday_detail(x) # 是否节假日（且节假日显示假日名称）
            if holiday_code[0]==True and holiday_code[1] is not None:
                ne_date_2022_holiday.append(holiday_code[1])
            else:
                ne_date_2022_holiday.append(None)
        ne_date_2022['holiday_code'] =ne_date_2022_holiday

        ne_date=pd.concat([ne_date_2022,ne_date_2022_after])
        ne_date = ne_date.sort_values(by=['date_range'], ascending=[True])
    else:
        # 节假日特征
        print(ne_date.year.unique())
        ne_date['is_workday'] = pd.DataFrame([is_workday(x) for x in ne_date['date']]).astype('int')  # 是否工作日
        ne_date['is_holiday'] = pd.DataFrame([is_holiday(x) for x in ne_datetime]).astype('int')  # 是否节假日
        holiday = []
        for x in ne_date['date']:
            holiday_code = get_holiday_detail(x)  # 是否节假日（且节假日显示假日名称）
            if holiday_code[0] == True and holiday_code[1] is not None:
                holiday.append(holiday_code[1])
            else:
                holiday.append(None)
        ne_date['holiday_code'] = holiday


    holidat_code = ne_date['holiday_code'].astype('category').cat.codes
    holiday_code_dict =  {code: category for code, category in enumerate(ne_date['holiday_code'].astype('category').cat.categories)}
    ne_date['holiday_code']=holidat_code
    #print ('---zheli',ne_date)
    return ne_date,holiday_code_dict

#以预测颗粒度为滑动窗口单位，生成滑动均值特征(必选增加特征值)
def add_period_sliding_window_features(data_predict,predict_lens):

    ts_2357 = pd.DataFrame()
    ts_00 = data_predict
    ts_001 = ts_00.shift(predict_lens)
    ts_002 = ts_001.rolling(window=2, center=False).mean()
    ts_003 = ts_001.rolling(window=3, center=False).mean()
    ts_005 = ts_001.rolling(window=5, center=False).mean()
    ts_007 = ts_001.rolling(window=7, center=False).mean()
    ts_007max = ts_001.rolling(window=7, center=False).max()
    ts_007min = ts_001.rolling(window=7, center=False).min()
    ts_2357 = pd.concat([ts_00, ts_001, ts_002, ts_003, ts_005, ts_007, ts_007max, ts_007min], axis=1,
                        keys=['predict1', '1_Period', '2_Period', '3_Period', '5_Period', '7_Period', '7_Period_max',
                              '7_Period_min'])  # ,'6','7','8','9','10','10max','10min',ts_006,ts_007,ts_008,ts_009,ts_010,ts_010max,ts_010min
    return ts_2357

#以天为滑动窗口，（以小时为周期，选择该特征值）
# 如滑动窗口1,为前一天同hour
# ts_002表示前1~2天该hour的均值
# 生成滑动均值特征
def add_hour_sliding_window_features(data_predict,predict_timeslots,predict_lens):
    shift_lens=int(predict_lens/24)+1
    ts_all1235 = pd.DataFrame()
    if predict_timeslots=='hour':
        for hour in range(0,24):
            ts_1235=pd.DataFrame()
            ts_00 = data_predict[data_predict['hour'] == hour].predict
            ts_001 = ts_00.shift(shift_lens)
            ts_005 = ts_001.rolling(window=5, center=False).mean()
            ts_010 = ts_001.rolling(window=10, center=False).mean()
            ts_015 = ts_001.rolling(window=15, center=False).mean()
            ts_020 = ts_001.rolling(window=20, center=False).mean()
            ts_010max = ts_001.rolling(window=10, center=False).max()
            ts_010min = ts_001.rolling(window=10, center=False).min()
            ts_1235 = pd.concat([ts_00, ts_001, ts_005, ts_010, ts_015, ts_020, ts_010max, ts_010min], axis=1,
                                keys=['predict2', '1_Day_Hour', '5_Day_Hour', '10_Day_Hour', '15_Day_Hour', '20_Day_Hour', '20max_Day_Hour',
                                      '20min_Day_Hour'])
            ts_all1235 = pd.concat([ts_all1235, ts_1235])

    return ts_all1235.sort_index()

#以周为滑动窗口，（以天为周期时，选择该特征值）
# 如预测时长为4天，则滑动窗口为前一个星期；若预测时长为10天，则滑动窗口为前2个星期
# 生成滑动均值特征
def add_week_sliding_window_features(data_predict,predict_timeslots,predict_lens):
    shift_lens = int(predict_lens/7)+1  #shift_lens为1，表示向前滑动一个星期
    ts_all1235 = pd.DataFrame()
    # print(data_predict.columns)
    # print(data_predict['dayofweek'])
    #data_predict['dayofweek']=data_predict['']
    if predict_timeslots == 'day':
        for week in range(0, 7):
            ts_1235 = pd.DataFrame()
            ts_00 = data_predict[data_predict['dayofweek'] == week].predict
            ts_001 = ts_00.shift(shift_lens)
            #print(week)
            #print('ts_00---',data_predict[data_predict['dayofweek'] == week][['datetime','predict']])
            ts_002 = ts_001.rolling(window=2, center=False).mean()
            ts_003 = ts_001.rolling(window=3, center=False).mean()
            # ts_004 = ts_001.rolling(window=4, center=False).mean()
            # ts_005 = ts_001.rolling(window=5, center=False).mean()
            # ts_005max = ts_001.rolling(window=5, center=False).max()
            # ts_005min = ts_001.rolling(window=5, center=False).min()
            # ts_1235 = pd.concat([ts_00, ts_001, ts_002, ts_003, ts_004, ts_005, ts_005max, ts_005min], axis=1,
            #                     keys=['predict3', '1_Week_Day', '2_Week_Day', '3_Week_Day', '4_Week_Day', '5_Week_Day',
            #                           '5max_Week_Day',
            #                           '5min_Week_Day'])
            ts_1235 = pd.concat([ts_00, ts_001, ts_002, ts_003], axis=1,
                                keys=['predict3', '1_Week_Day', '2_Week_Day', '3_Week_Day'])
            ts_all1235 = pd.concat([ts_all1235, ts_1235])

    return ts_all1235.sort_index()

#
# # 以节假日为滑动窗口，（以小时为周期，选择该特征值）
# # 如预测时长为4天，则滑动窗口为前一个星期；若预测时长为10天，则滑动窗口为前2个星期
# # 生成滑动均值特征
# def add_holiday_sliding_window_features(data_predict, predict_timeslots, predict_lens,year):
#     ts_all1235 = pd.DataFrame()
#     for holiday_code in holiday_code_dir:
#         ts_1235 = pd.DataFrame()
#         ts_00 = data_predict[data_predict['holiday_code'] == holiday_code]
#         last_holiday_data=ts_00[ts_00['year']==year-1]
#         today_holiday_data=ts_00[ts_00['year']==year]
#         #TODO 如果前一个节假日的数据不存在，则该特征为NaN,不好训练模型，待修改
#         if len(today_holiday_data)!=0:
#             today_holiday_data['last_holiday_data_mean']=last_holiday_data.predict.mean()
#         if len(today_holiday_data)==len(last_holiday_data):
#             today_holiday_data['last_holiday_data'] = list(last_holiday_data.predict)
#         elif len(today_holiday_data)<len(last_holiday_data):
#             today_holiday_data['last_holiday_data']=list(last_holiday_data.predict[0:len(today_holiday_data)])
#         elif len(today_holiday_data) > len(last_holiday_data):
#             today_holiday_data['last_holiday_data'] =last_holiday_data.predict.mean()
#
#         #前一个节假日前7天日常平均值
#         last_holiday_normal=data_predict[data_predict['datetime']<last_holiday_data.datetime.iloc[0]]
#
#         if predict_timeslots=='hour' and len(last_holiday_normal)>7*24:
#             today_holiday_data['last_holiday_normal_data_mean']=last_holiday_normal[-24*7:].predict.mean()
#         elif predict_timeslots=='hour' and len(last_holiday_normal)<=7*24:
#             today_holiday_data['last_holiday_normal_data_mean'] = last_holiday_normal.predict.mean()
#
#         elif predict_timeslots == 'day' and len(last_holiday_normal) > 7:
#             today_holiday_data['last_holiday_normal_data_mean'] = last_holiday_normal[-7:].predict.mean()
#         elif predict_timeslots == 'day' and len(last_holiday_normal) <=7:
#             today_holiday_data['last_holiday_normal_data_mean'] = last_holiday_normal.predict.mean()
#
#         ts_1235=today_holiday_data
#         ts_all1235 = pd.concat([ts_all1235, ts_1235])
#     return ts_all1235

#缺失值预测填充
def fill_null_data(train_x,train_y,test_x):
    # cv_split = TimeSeriesSplit(n_splits=4, test_size=90)
    # model = XGBRegressor()
    # parameters = {
    #     "max_depth": [3, 4, 6, 5, 10],
    #     "learning_rate": [0.01, 0.05, 0.1, 0.2, 0.3],
    #     "n_estimators": [100, 300, 500, 700, 900, 1000],
    #     "colsample_bytree": [0.3, 0.5, 0.7]
    # }

    # # LGBM
    # cv_split = TimeSeriesSplit(n_splits=2, test_size=60)
    # model = lgb.LGBMRegressor()
    # parameters = {
    #     "max_depth": [3, 4, 6, 5, 10],
    #     "num_leaves": [10, 20, 30, 40, 100, 120],
    #     "learning_rate": [0.01, 0.05, 0.1, 0.2, 0.3],
    #     "n_estimators": [50, 100, 300, 500, 700, 900, 1000],
    #     "colsample_bytree": [0.3, 0.5, 0.7, 1]
    # }
    #
    #
    #
    # # grid_search = GridSearchCV(estimator=model, cv=cv_split, param_grid=parameters)
    # grid_search=RandomizedSearchCV(model, parameters, cv=cv_split, scoring='neg_mean_squared_error', n_iter=6, n_jobs=-1)
    # print('test predict....111')
    # #
    # grid_search.fit(train_x, train_y)
    # y_pred = grid_search.predict(test_x)
    # print('test predict....222')

    model1 = xgb.XGBRegressor(base_score=0.5,
                              colsample_bylevel1=1,
                              learning_rate=0.2,  # 0.1
                              max_delta_step=0,
                              n_estimators=500,
                              nthread=1,
                              scale_pos_weight=1,
                              seed=1850,
                              silent=True,
                              min_child_weight=3,
                              max_depth=7,
                              gamma=0,
                              colsample_bytree=0.75,
                              subsample=0.85,
                              reg_alpha=0.000065,
                              reg_lambda=0.29,
                              objective='reg:linear')
    print(u'xgboost开始建模：缺失值填充...')
    model1.fit(train_x, train_y)
    model2 = RandomForestRegressor(criterion='mae',
                                   max_depth=5,
                                   oob_score=True,
                                   random_state=0,
                                   max_features='auto',
                                   n_estimators=50
                                   )
    print(u'RF开始建模：缺失值填充...')
    model2.fit(train_x, train_y)
    ##    y_train_pred = 0.2*model1.predict(x_train)+0.8*model2.predict(x_train)
    print(test_x)
    y_pred = 0.2 * model1.predict(test_x) + 0.8 * model2.predict(test_x)

    # y_pred =  model1.predict(test_x)
    # predict_train_result = 0.2 * model1.predict(train_x) + 0.8 * model2.predict(train_x)
    #predict_train_result = model.predict(train_x)
    #model_score_train = metrics.r2_score(train_y, predict_train_result)
    model_score_train=0
    print('结束建模')
    return y_pred,model_score_train






def LSTM_predict(all_data_predict,predict_lens,response):
    response['start_LSTM_predict'] = True

    data_00 = all_data_predict.drop(['predict1', 'predict2'], axis=1)
    data_00.index = data_00.datetime
    # data=data[['day','hour','dayofweek','t-24','after_fill']]
    data_00['date'] = [str(x).replace('-', '') for x in data_00.date]  # 日期  20220522

    features = list(set(data_00.columns) - set(['datetime', 'ne_name']))

    values = data_00[features]  # dataframe转化为二维数组
    values = values.astype('float64')
    scaler = MinMaxScaler(feature_range=(0, 1))
    scaled = scaler.fit_transform(values)
    scaled = pd.DataFrame(scaled)
    # df1=pd.concat([scaled,data[['day','hour','dayofweek']]],axis=1)
    df1 = scaled
    # df1.columns=['after_fill','t-1','day','hour','dayofweek']
    df1.columns = features
    # data = pd.read_csv('one_noid_drop_repeat/615152704565986819.csv',encoding='utf-8')
    x_features2 = list(set(values.columns) - set(['predict']))
    train, test = df1[:-predict_lens], df1[-predict_lens:]
    train = train.dropna()

    trainX = train[x_features2]
    trainY = train['predict']

    testX = test[x_features2]  #
    testY = test['predict']  #

    test_all_X = pd.concat([trainX, testX])
    test_all_Y = pd.concat([trainY, testY])
    #
    # #########################
    # # reshape input to be [samples, time steps, features]
    # #TODO reshape(1:表示timestep，输出步长，需要修改)
    #
    trainX = trainX.values.reshape((trainX.shape[0], 1, trainX.shape[1]))
    testX1 = testX.values.reshape((testX.shape[0], 1, testX.shape[1]))
    test_all_X1 = test_all_X.values.reshape((test_all_X.shape[0], 1, test_all_X.shape[1]))

    ####################################################################

    trainX = K.cast_to_floatx(trainX)
    trainY = K.cast_to_floatx(trainY)
    testX1 = K.cast_to_floatx(testX1)
    testY = K.cast_to_floatx(testY)

    model = Sequential()
    # model.add(LSTM(500, input_shape=(1, 1)))
    # TODO input_shape(1:表示timestep，输出步长，需要修改)
    model.add(LSTM(4, input_shape=(1, len(x_features2))))
    model.add(Dense(1))  # 输出为1维
    # model.compile(loss='mean_squared_error', optimizer='adam')
    model.compile(loss='mae', optimizer='adam')
    # model.fit(trainX, trainY, epochs=100, batch_size=1, verbose=2)
    model.fit(trainX, trainY, epochs=24, batch_size=1, verbose=2)
    # make predictions
    # trainPredict = model.predict(trainX)
    # print(trainPredict[:,0]) #数组和dataframe取列表达方式不一样，dataframe需要用
    testPredict = model.predict(testX1)
    response['finish_LSTM_predict'] = True

    testX = testX.reset_index(drop=True)
    inv_yhat = pd.concat([pd.DataFrame(testPredict[:, 0]), testX], axis=1)
    inv_yhat = scaler.inverse_transform(inv_yhat.values)
    inv_yhat = inv_yhat[:, 0]

    # 计算LSTM模型的训练得分
    trainPredict = model.predict(trainX)
    train_all_X = train[x_features2].reset_index(drop=True)
    inv_yhat1 = pd.concat([pd.DataFrame(trainPredict[:, 0]), train_all_X], axis=1)
    inv_yhat1 = scaler.inverse_transform(inv_yhat1.values)
    inv_yhat1 = inv_yhat1[:, 0]
    model_score_train = metrics.r2_score(trainY, inv_yhat1)

    return model_score_train,inv_yhat


def roundkpi(m,n):
    return round(m*(10**n))/(10**n)


def predict_algorithms(request):
    response={}
    response['get_data'] = False  #默认为False,成功获取数据之后，则为True
    response['get_datetime_for_null'] = False  #默认为False,补齐缺失值的时间戳后，成功增加时间特征值,则为True
    #response['exits_null_data'] = True  存在缺失值时，则为True，否则无该参数
    #response['fill_null_data'] = True  存在缺失值时，成功预测填充该缺失值，则为True,否则无该参数
    #response['fill_null_data_error_code'] = True  存在缺失值时，预测填充该缺失值失败时，返回失败原因值
    response['add_predict_time_features'] = False #默认为False，成功增加预测数据的时间特征后，则为True
    response['add_predict_sliding_features'] = False #默认为False，成功增加预测数据的滑动窗口特征后，则为True


    if request.method=='POST':
        print('starting------------------------------------------------------------------------')
        # print(type(request.headers),request.headers)
        # print(type(request.POST), request.POST)
        # param = ReportCollector.url('/app-w2zqz94632vvzx/predict_algorithms/', False) \
        #     .header_param(request.headers.get('ability_invoking_param'))

        if request.headers.get('Content-Type')=='application/x-www-form-urlencoded':
            # print(type(request.POST), request.POST)
            predict_methods=request.POST.get('predict_methods')
            # print('........',predict_methods)
            predict_timeslots = request.POST.get('predict_timeslots')
            predict_lens=int(request.POST.get('predict_lens'))
            data=request.POST.get('data')
        else:
            # print(type(request.body),request.body)
            input_data=json.loads(request.body.decode('utf-8'), strict=False)
            predict_methods=input_data.get('predict_methods')
            # print('........',predict_methods)
            predict_timeslots = input_data.get('predict_timeslots')
            predict_lens=int(input_data.get('predict_lens'))
            data=input_data.get('data')
        # data=pd.json_normalize(data)
        # print(json.loads(str(data)))
        # data=pd.json_normalize(json.loads(str(data)))
        if type(data) is list:
            print('list_type')
            data=pd.DataFrame(data)
        elif type(data) is str:
            print('str_type')
            data=pd.json_normalize(json.loads(str(data)))
        print(data.shape)

        input={}
        input['predict_methods']=predict_methods
        input['predict_timeslots']=predict_timeslots
        input['predict_lens']=predict_lens
        input['data']=data

        # predict_methods=request.POST['predict_methods']
        # predict_timeslots = request.POST['predict_timeslots']
        # predict_lens=int(request.POST['predict_lens'])
        #
        # data=request.POST['data']
        # data=pd.json_normalize(json.loads(data))
        response['get_data']=True
        # print(response)
        # param.multi_param(input)
#################本地测试######################################
        # predict_methods=parameter['predict_methods']
        # predict_lens=parameter['predict_lens']
        # predict_timeslots=parameter['predict_timeslots']
        # data=pd.json_normalize(json.loads(parameter['data']))
#######################################################

        try:
            #重命名前3列字段名称
            columns=data.columns
            data.rename(columns = {columns[0]: 'datetime', columns[1]:'ne_name',columns[2]:'predict'}, inplace=True)
            #处理datetime字段，生成整个时间段（训练+预测）
            data['datetime'] = pd.to_datetime(data['datetime']).dt.strftime('%Y-%m-%d %H:%M:%S')
            data['datetime'] = pd.to_datetime(data['datetime'])
            data=data.sort_values(by=['datetime'],ascending=[True])

            date1=pd.to_datetime('2022-10-1 10:00:00')
            date2=pd.to_datetime('2022-10-1 11:00:00')
            date3=pd.to_datetime('2022-10-2 10:00:00')

            if predict_timeslots =='day':
                timedelta=date3-date1
            elif predict_timeslots =='hour':
                timedelta=date2-date1

            #print('input_data',data)
    ################################################################################################
    ################################################################################################
    #一、处理缺失数据
            #1、根据缺失值数量，生成日期区间
            start_time=str(data['datetime'][0])
            end_time=str(data['datetime'][len(data)-1])
            # print(start_time,end_time,'freq')
            freq=str(int(timedelta.total_seconds()/60))+'min'
            #print(freq)

            date_range = pd.date_range(start=start_time,end=end_time,freq =freq )
            # print(date_range)
            #整合原始数据和日期区间
            all_data=pd.merge(pd.DataFrame(date_range,columns=['date_range']),data,left_on='date_range',right_on='datetime',how='outer')
            #print("zhelikaishi---",all_data['date_range'])
    ################################################################################################
            #2、处理输入数据，增加时间特征值
            #date_time_features,holiday_code_dir=add_time_features(all_data['date_range'])  #处理输入数据，增加时间特征值
            #all_data=pd.merge(all_data,date_time_features,left_on='date_range',right_on='date_range',how='outer')
            all_data['date_range']=pd.to_datetime(all_data['date_range'])
            #all_data['date_range']=all_data['date_range'].dt.strftime('%Y-%m-%d %H:%M:%S')
            all_data['datetime']=pd.to_datetime(all_data['date_range'])
            #all_data['date_range']=all_data['date_range'].apply(lambda x: dt.datetime.strptime(x, '%Y-%m-%d %H:%M:%S').timestamp()) #This is not UTC. It does not really matter.
            #print('aaaaaaaaaaa')
            response['get_datetime_for_null']=True

    ################################################################################################

            #3、处理缺失数据，预测填补缺失值
            test_data_isnull=all_data[all_data['predict'].isnull()]    #缺失值，待填充
            train_data_notnull=all_data[all_data['predict'].notnull()]#非缺失值，用于训练
            #如果无缺失值，则不用预测填补
            del_features = ['datetime', 'ne_name', 'predict']
            if test_data_isnull is not None:
                response['exits_null_data'] = True

                columns_type_dir=train_data_notnull.dtypes
                #xgboost：数据类型必须是int、float或bool
                true_type=['int','float','bool']
                for column in columns_type_dir.keys():
                    if columns_type_dir[column] not in true_type:
                        try:
                            train_data_notnull[column]=pd.to_numeric(train_data_notnull[column])
                            test_data_isnull[column]=pd.to_numeric(test_data_isnull[column])
                        except Exception as e:
                            del_features.append(column)
                #生成训练集和测试集
                x_features=list(set(train_data_notnull.columns)-set(del_features))
                train_x=train_data_notnull[x_features]
                train_y=train_data_notnull['predict']
                test_x=test_data_isnull[x_features]

                #预测填补缺失值
                all_data['predict']=all_data['predict'].fillna(method='ffill')
                # try:
                #     y_pred,model_score_train_fill=fill_null_data(train_x,train_y,test_x)
                #     all_data['predict'][all_data['predict'].isnull()] = y_pred
                # except Exception as e:
                #     response['fill_null_data_error_code'] = str(e)  #存在缺失值时，预测填充该缺失值失败时，返回失败原因值

                response['fill_null_data'] = True
                # print(response)
    ################################################################################################
    ################################################################################################
    #二、 增加预测时间段的特征值---增加时间特征值
            #1、生成预测时间
            predict_end_time=pd.to_datetime(end_time)+timedelta*predict_lens
            date_range2 = pd.date_range(start=end_time, end=predict_end_time, freq=freq)[1:]
            predict_date=pd.DataFrame(date_range2, columns=['date_range'])
            # 合并原始数据和预测日期
            # date_time_features2, holiday_code_dir2 = add_time_features(predict_date['date_range'])  # 处理输入数据，增加时间特征值
            # print('tttt',date_time_features2)
            # date_time_features2['datetime']=date_time_features2['date_range']
            # date_time_features2['date_range'] = date_time_features2['date_range'].dt.strftime('%Y-%m-%d %H:%M:%S')
            # date_time_features2['date_range'] = date_time_features2['date_range'].apply(lambda x: dt.datetime.strptime(x,
            #                                                                                                            '%Y-%m-%d %H:%M:%S').timestamp())  # This is not UTC. It does not really matter.
            predict_date['datetime']=predict_date['date_range']
            #print(all_data.columns,predict_date.columns)
            all_data_predict = pd.concat([all_data, predict_date])
            all_data_predict=all_data_predict.reset_index(drop=True)

            print('zhelikaishi------bug test')
            all_data_predict['date_range']=pd.to_datetime(all_data_predict['date_range'])
            date_time_features,holiday_code_dir=add_time_features(all_data_predict['date_range'])  #处理输入数据，增加时间特征值
            all_data_predict=pd.merge(all_data_predict,date_time_features,left_on='date_range',right_on='date_range',how='outer')
            print('开始调整。。。')

            all_data_predict.loc[all_data_predict['predict']==0,'predict']=np.nan
            all_data_predict['data_normal_day']=all_data_predict['predict']
            all_data_predict.loc[all_data_predict['holiday_code']!=-1,'data_normal_day']=np.nan
            all_data_predict['data_normal_window_day_means']=all_data_predict['data_normal_day'].shift(20).rolling(window=41,min_periods=1).mean()
            all_data_predict['change_precent_window_means']=(all_data_predict['predict']-all_data_predict['data_normal_window_day_means'])/all_data_predict['data_normal_window_day_means']*100
            print('开始调整。。。')

            for i in range(len(all_data_predict)-predict_lens,len(all_data_predict)):
                if pd.isnull(all_data_predict['data_normal_window_day_means'].iloc[i]):
                    all_data_predict['data_normal_window_day_means'][i] = all_data_predict['data_normal_window_day_means'][i -42:i].mean()
                if all_data_predict['holiday_code'][i]==-1 and pd.isnull(all_data_predict['change_precent_window_means'].iloc[i]):
                    all_data_predict['change_precent_window_means'][i] = all_data_predict['change_precent_window_means'][i -42:i].mean()
            print('开始调整。。。')

            for i in range(len(all_data_predict) - predict_lens, len(all_data_predict)):
                if all_data_predict['holiday_code'][i]!=-1 and pd.isnull(all_data_predict['change_precent_window_means'].iloc[i]):
                    year=all_data_predict['year'].iloc[i]
                    holiday_code=all_data_predict['holiday_code'].iloc[i]
                    if len(all_data_predict[(all_data_predict['year'] ==year-1) & (all_data_predict['holiday_code'] ==holiday_code)]['change_precent_window_means'])>0:
                        change_precent_window_means=all_data_predict[(all_data_predict['year'] ==year-1) & (all_data_predict['holiday_code'] ==holiday_code)]['change_precent_window_means'].iloc[0]
                        all_data_predict['change_precent_window_means'][i] = change_precent_window_means
            print('开始调整。。。')
            all_data_predict['change_precent_window_means']=all_data_predict['change_precent_window_means'].fillna(method='ffill')
            all_data_predict['data_normal_window_day_means']=all_data_predict['data_normal_window_day_means'].fillna(method='ffill')
            #待修改成-删除节假日的均值前向填充
            #all_data_predict['change_precent_window_means']=all_data_predict['change_precent_window_means'].fillna(method='ffill')

            all_data_predict = all_data_predict.sort_values(by='datetime')
            all_data_predict = all_data_predict.reset_index(drop=True)


            all_data_predict['predict_rate_result'] = all_data_predict['data_normal_window_day_means'] * (1 + all_data_predict['change_precent_window_means'] / 100)
            # all_data_predict=all_data_predict.fillna(method='ffill')

            print('111开始调整。。。')

            # year_mean=mean_holiday_data.groupby(['year'], as_index=False)['mean_predict'].first()
            # year_mean=year_mean.set_index(['year'])
            #mean_holiday_data = pd.merge(mean_holiday_data,quarter_mean,left_on=['year'],right_on=['year'])

            print('holiday_code::::',holiday_code_dir)

            response['add_predict_time_features'] = True

            all_data_predict = all_data_predict.sort_values(by='datetime')
            all_data_predict=all_data_predict.reset_index(drop=True)

            #2-1滑动窗口特征，以预测时长为周期（必选特征值）
            # 说明：取前1-7的移动平均值，
            # 则‘1’为前1个预测时长前1天的值，‘2’为前1个预测时长前2天的平均值，以此类推；5max为这5个移动平均值中最大的值
            date_time_features3=add_period_sliding_window_features(all_data_predict['predict'],predict_lens)
            all_data_predict=pd.concat([all_data_predict,date_time_features3],axis=1)
            all_data_predict = all_data_predict.sort_values(by='datetime')
            all_data_predict=all_data_predict.reset_index(drop=True)
            # 2-2滑动窗口特征（以小时为预测颗粒度时，选择该类特征值）
            # 以天为周期的移动窗口平均，以及取最大值、最小值
            date_time_features4=add_hour_sliding_window_features(all_data_predict, predict_timeslots, predict_lens)
            all_data_predict=pd.concat([all_data_predict,date_time_features4],axis=1)
            all_data_predict = all_data_predict.sort_values(by='datetime')
            all_data_predict=all_data_predict.reset_index(drop=True)
            #2-3滑动窗口特征（以天为周期时，选择该类特征值）
            # 以星期为周期的移动窗口平均，以及取最大值、最小值
            date_time_features5=add_week_sliding_window_features(all_data_predict, predict_timeslots, predict_lens)
            # print('date_time_features5',date_time_features5.predict3)
            all_data_predict=pd.concat([all_data_predict,date_time_features5],axis=1)
            all_data_predict = all_data_predict.sort_values(by='datetime')
            all_data_predict=all_data_predict.reset_index(drop=True)

            response['add_predict_sliding_features'] = True
            #print('add_predict_sliding_features')


            #三、LSTM/xgvoost算法预测
            if predict_methods=='LSTM':
                model_score_train,inv_yhat=LSTM_predict(all_data_predict,predict_lens, response)
                response['predict_result']=list(inv_yhat)
                response['model_score_train']=model_score_train
            if predict_methods=='XGBoost':
                response['start_XGBoost_predict']=True

                all_data_predict = all_data_predict.sort_values(by='datetime')
                all_data_predict=all_data_predict.reset_index(drop=True)

                test_data_isnull = all_data_predict[-predict_lens:]  # 缺失值，待填充
                # test_data_isnull=test_data_isnull[(test_data_isnull['holiday_code']==-1) | (test_data_isnull['holiday_code']==5)]

                print('---------test_data_isnull',test_data_isnull)
                train_data_notnull = all_data_predict[0:-predict_lens]  # 非缺失值，用于训练
                train_data_notnull=train_data_notnull.dropna()
                # train_data_notnull=train_data_notnull[(train_data_notnull['holiday_code']==-1) | (train_data_notnull['holiday_code']==5)]

                # xgboost：数据类型必须是int、float或bool
                del_features = ['data_normal_window_day_means','holiday_code','predict_rate_result','change_precent_window_means','data_normal_day','minute','datetime', 'ne_name', 'predict','predict1','predict2','predict3','quarter','dayofyear','mean_predict','predict_quarter_mean','predict_quarter_mean_shift1','predict_mean_now_x']
                columns_type_dir = train_data_notnull.dtypes
                # xgboost：数据类型必须是int、float或bool
                true_type = ['int', 'float', 'bool']
                for column in columns_type_dir.keys():
                    if columns_type_dir[column] not in true_type:
                        try:
                            train_data_notnull[column] = pd.to_numeric(train_data_notnull[column])
                            test_data_isnull[column] = pd.to_numeric(test_data_isnull[column])
                        except Exception as e:
                            del_features.append(column)
                # 生成训练集和测试集
                x_features = list(set(train_data_notnull.columns) - set(del_features))
                #x_features =[ 'change_precent', 'holiday_code','predict_quarter_mean','predict_quarter_mean_shift1','mean_predict']
                 #                - set(del_features))

                print(list(set(train_data_notnull.columns)))
                train_x_for_XGB = train_data_notnull[x_features]
                train_y_for_XGB = train_data_notnull['predict']

                test_x_for_XGB = test_data_isnull[x_features]
                #print(test_x_for_XGB)

                datetime_predict=test_data_isnull['datetime']
                print(train_x_for_XGB,train_y_for_XGB)
                print(test_x_for_XGB,test_data_isnull['date'])
                # 预测
                predict_result,model_score_train_predict= fill_null_data(train_x_for_XGB, train_y_for_XGB, test_x_for_XGB)
                response['finish_XGBoost_predict']=True
                predict_out=pd.DataFrame()
                datetime_predict = pd.to_datetime(datetime_predict).dt.strftime('%Y-%m-%d %H:%M:%S')

                # print(datetime_predict,train_data_notnull['ne_name'].unique()[0])
                predict_out['datetime']=list(datetime_predict)
                predict_out['ne_name']=train_data_notnull['ne_name'].unique()[0]
                predict_out['predict_rate_result']=list(test_data_isnull['predict_rate_result'])
                predict_out['predict_result']=list(predict_result)
                predict_out['holiday_code']=list(test_data_isnull['holiday_code'])
                predict_out['data_normal_window_day_means']=list(test_data_isnull['data_normal_window_day_means'])
                predict_out['change_precent_window_means']=list(test_data_isnull['change_precent_window_means'])
                predict_out['predict_result_2']=predict_out['predict_result']*(1+predict_out['change_precent_window_means']/100)


                response['predict_result']=predict_out.to_json(orient="records")
                # sdk_response=deepcopy(response)
                # print('sdkrespones:',sdk_response)

                # if not isinstance(response, dict):
                #     try:
                #         output_dict = json.loads(response)
                #     except Exception as ex:
                #         print(ex)
                # else:
                #     print("这里")
                #     output_dict = response
                #
                # print("finally response1.............:", output_dict)

            #print(response)
            # param.is_success(True).response_code(200).output_data(sdk_response)
            response['model_score_train'] = model_score_train_predict

        except Exception as ex:
            print('ex:',ex)
            # param.is_success(False).response_code(500).output_data(sdk_response)
            print("ex= ", ex)
        finally:
            print('success')
            # report_service.report(param)

    response_final=[]
    response_final.append(response)
    return response_final




